package com.partsoft.dits.integrate;

import java.util.Map;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.ContextStoppedEvent;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;

import com.partsoft.dits.BaseRegistryDescriptorResolver;
import com.partsoft.dits.ConfigurableBean;
import com.partsoft.dits.DescriptorRegistry;
import com.partsoft.dits.DescriptorResolver;
import com.partsoft.dits.EdgeDescriptor;

@SuppressWarnings("rawtypes")
public class ContextRegistryDescriptorResolver extends
		BaseRegistryDescriptorResolver implements DescriptorResolver,
		ApplicationContextAware, ApplicationListener<ApplicationEvent>,
		ConfigurableBean {
	
	private ApplicationContext ownerContext;

	private boolean inited = false;

	public void finiContext() {
		synchronized (this) {
			clearRegistries();
			inited = false;
		}
	}

	public void initContext() {
		Assert.notNull(getOwnerContext());
		synchronized (this) {
			if (inited) finiContext();
			Map<String, DescriptorRegistry> beans = getOwnerContext().getBeansOfType(DescriptorRegistry.class);
			for (DescriptorRegistry<? extends EdgeDescriptor> reg : beans.values()) {
				addRegistry(reg);
			}
			inited = true;
		}
	}

	public void onApplicationEvent(ApplicationEvent event) {
		if (getOwnerContext() == null) return;
		if (!ObjectUtils.nullSafeEquals(getOwnerContext(), event.getSource())) return;
		if (event instanceof ContextRefreshedEvent) {
			initContext();
		} else if (event instanceof ContextStoppedEvent) {
			finiContext();
		}
	}
	
	public ApplicationContext getOwnerContext() {
		return ownerContext;
	}

	public void setApplicationContext(ApplicationContext arg0)
			throws BeansException {
		this.ownerContext = arg0;
	}

}
